namespace RL

open Raylib_CsLo
open System.Numerics

module Components =
     /// Tag struct to mark an entity as the player.
    type Player = struct end
     /// Tag struct to mark an entity as hostile.
    type Enemy = struct end
     /// Tag struct which marks the entity as a blockage to movement.
    type BlocksMovement = struct end

    /// Container struct to store a sprite-sheet index.
    type Sprite = { spriteID : int; color : Color }

    /// Integer-based 2D vector for in-game position tracking.
    type Point2D = { x : int; y : int } with
        static member (+)(a : Point2D, b : Point2D) = { x = a.x + b.x; y = a.y + b.y }
        static member (-)(a : Point2D, b : Point2D) = { x = a.x - b.x; y = a.y - b.y }

        static member Up =         { x = 0; y = -1 }
        static member Down =       { x = 0; y = 1 }
        static member Left =       { x = -1; y = 0 }
        static member Right =      { x = 1; y = 0 }
        static member UpLeft =     { x = -1; y = -1 }
        static member UpRight =    { x = 1; y = -1 }
        static member DownLeft =   { x = -1; y = 1 }
        static member DownRight =  { x = 1; y = 1 }

        member p.ToVector = Vector2(single p.x, single p.y)
        member _.Neighbors =
            [Point2D.Up; Point2D.Down;
            Point2D.Left; Point2D.Right;
            Point2D.UpLeft; Point2D.UpRight;
            Point2D.DownLeft; Point2D.DownRight]

    type Health = { mutable current : int; max : int } with
        member h.Set(v : int) = h.current <- max 0 (min v h.max)
        member h.Gain(v : int) = h.current <- max 0 (min (h.current + v) h.max)
        member h.Lose(v : int) = h.current <- max 0 (min (h.current - v) h.max)

    type CombatStats = { damage : int; defense : int; }
